package main

import (
	"fmt"
	"io"
	"os"
	"reflect"
)

func main() {
	//emptyInterWithConcreteType()
	//noEmptyInterWithConcreteType()
	//emptyInterWithNoEmptyInter()
	noEmptyInterWithNoEmptyInter()
}

type eggo struct {
	name string
}

//空接口.(具体类型)
func emptyInterWithConcreteType() {
	//断言成功，空接口e的动态类型itab指向的是os.*File，断言的动态类型是os.*File
	var e interface{}
	f, _ := os.Open("eggo.txt")
	e = f
	fmt.Printf("type:%v \n", reflect.TypeOf(e))
	r, ok := e.(*os.File)
	fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(r), ok)

	//断言失败，空接口e的动态类型itag指向main.eggo，断言的动态类型是os.*File
	e = eggo{name: "eggo"}
	fmt.Printf("type:%v \n", reflect.TypeOf(e))
	rr, ok := e.(*os.File)
	fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(rr), ok)
}

//非空接口.(具体类型)
func noEmptyInterWithConcreteType() {
	//断言成功，e的接口类型是io.ReadWriter，动态类型是os.*File，断言的动态类型也是os.*File
	var e io.ReadWriter
	f, _ := os.Open("eggo.txt")
	e = f
	fmt.Printf("type:%v \n", reflect.TypeOf(e))
	r, ok := e.(*os.File)
	fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(r), ok)

	//编译出错，io.Writer 是io.ReadWriter的父类，并未实现Reader方法
	//断言失败，e的接口类型是io.Writer，动态类型itab指向main.eggo，断言的动态类型是os.*File
	// var a io.Writer
	// e = a
	// fmt.Printf("type:%v \n", reflect.TypeOf(e))
	// rr, ok := e.(*os.File)
	// fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(rr), ok)
}

//空接口.(非空接口)
func emptyInterWithNoEmptyInter() {
	//断言成功，e的动态类型是os.*File，断言的动态类型io.ReadWriter。os.*File实现了io.ReadWriter的所有方法
	var e interface{}
	f, _ := os.Open("eggo.txt")
	e = f
	fmt.Printf("type:%v \n", reflect.TypeOf(e))
	r, ok := e.(io.ReadWriter)
	fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(r), ok)
}

func noEmptyInterWithNoEmptyInter() {
	//断言成功，e的接口类型是io.Writer，动态类型是os.*File，断言的动态类型io.ReadWriter。os.*File实现了io.ReadWriter的所有方法
	var e io.Writer
	f, _ := os.Open("eggo.txt")
	e = f
	fmt.Printf("type:%v \n", reflect.TypeOf(e))
	r, ok := e.(io.ReadWriter)
	fmt.Printf("type:%v,ok:%v \n", reflect.TypeOf(r), ok)
}
